package com.tbi.graphcolouring.testers;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.tbi.graphcolouring.AlgorithmSettings;
import com.tbi.graphcolouring.BaseGraph;
import com.tbi.graphcolouring.BaseGraph.Node;
import com.tbi.graphcolouring.utils.Random;

public class GraphRepairTest {
	public static void main(String[] args) {
		BaseGraph graph = new BaseGraph(25);
		graph.addConnection(1 ,7       );
		graph.addConnection(1 ,13      );
		graph.addConnection(1 ,19      );
		graph.addConnection(1 ,25      );
		graph.addConnection(1 ,2       );
		graph.addConnection(1 ,3       );
		graph.addConnection(1 ,4       );
		graph.addConnection(1 ,5       );
		graph.addConnection(1 ,6       );
		graph.addConnection(1 ,11      );
		graph.addConnection(1 ,16      );
		graph.addConnection(1 ,21      );
		graph.addConnection(2 ,8       );
		graph.addConnection(2 ,14      );
		graph.addConnection(2 ,20      );
		graph.addConnection(2 ,6       );
		graph.addConnection(2 ,3       );
		graph.addConnection(2 ,4       );
		graph.addConnection(2 ,5       );
		graph.addConnection(2 ,7       );
		graph.addConnection(2 ,12      );
		graph.addConnection(2 ,17      );
		graph.addConnection(2 ,22      );
		graph.addConnection(2 ,1       );
		graph.addConnection(3 ,9       );
		graph.addConnection(3 ,15      );
		graph.addConnection(3 ,7       );
		graph.addConnection(3 ,11      );
		graph.addConnection(3 ,4       );
		graph.addConnection(3 ,5       );
		graph.addConnection(3 ,8       );
		graph.addConnection(3 ,13      );
		graph.addConnection(3 ,18      );
		graph.addConnection(3 ,23      );
		graph.addConnection(3 ,2       );
		graph.addConnection(3 ,1       );
		graph.addConnection(4 ,10      );
		graph.addConnection(4 ,8       );
		graph.addConnection(4 ,12      );
		graph.addConnection(4 ,16      );
		graph.addConnection(4 ,5       );
		graph.addConnection(4 ,9       );
		graph.addConnection(4 ,14      );
		graph.addConnection(4 ,19      );
		graph.addConnection(4 ,24      );
		graph.addConnection(4 ,3       );
		graph.addConnection(4 ,2       );
		graph.addConnection(4 ,1       );
		graph.addConnection(5 ,9       );
		graph.addConnection(5 ,13      );
		graph.addConnection(5 ,17      );
		graph.addConnection(5 ,21      );
		graph.addConnection(5 ,10      );
		graph.addConnection(5 ,15      );
		graph.addConnection(5 ,20      );
		graph.addConnection(5 ,25      );
		graph.addConnection(5 ,4       );
		graph.addConnection(5 ,3       );
		graph.addConnection(5 ,2       );
		graph.addConnection(5 ,1       );
		graph.addConnection(6 ,12      );
		graph.addConnection(6 ,18      );
		graph.addConnection(6 ,24      );
		graph.addConnection(6 ,7       );
		graph.addConnection(6 ,8       );
		graph.addConnection(6 ,9       );
		graph.addConnection(6 ,10      );
		graph.addConnection(6 ,11      );
		graph.addConnection(6 ,16      );
		graph.addConnection(6 ,21      );
		graph.addConnection(6 ,2       );
		graph.addConnection(6 ,1       );
		graph.addConnection(7 ,13      );
		graph.addConnection(7 ,19      );
		graph.addConnection(7 ,25      );
		graph.addConnection(7 ,11      );
		graph.addConnection(7 ,8       );
		graph.addConnection(7 ,9       );
		graph.addConnection(7 ,10      );
		graph.addConnection(7 ,12      );
		graph.addConnection(7 ,17      );
		graph.addConnection(7 ,22      );
		graph.addConnection(7 ,6       );
		graph.addConnection(7 ,3       );
		graph.addConnection(7 ,2       );
		graph.addConnection(7 ,1       );
		graph.addConnection(8 ,14      );
		graph.addConnection(8 ,20      );
		graph.addConnection(8 ,12      );
		graph.addConnection(8 ,16      );
		graph.addConnection(8 ,9       );
		graph.addConnection(8 ,10      );
		graph.addConnection(8 ,13      );
		graph.addConnection(8 ,18      );
		graph.addConnection(8 ,23      );
		graph.addConnection(8 ,7       );
		graph.addConnection(8 ,6       );
		graph.addConnection(8 ,4       );
		graph.addConnection(8 ,3       );
		graph.addConnection(8 ,2       );
		graph.addConnection(9 ,15      );
		graph.addConnection(9 ,13      );
		graph.addConnection(9 ,17      );
		graph.addConnection(9 ,21      );
		graph.addConnection(9 ,10      );
		graph.addConnection(9 ,14      );
		graph.addConnection(9 ,19      );
		graph.addConnection(9 ,24      );
		graph.addConnection(9 ,8       );
		graph.addConnection(9 ,7       );
		graph.addConnection(9 ,6       );
		graph.addConnection(9 ,5       );
		graph.addConnection(9 ,4       );
		graph.addConnection(9 ,3       );
		graph.addConnection(10, 14     );
		graph.addConnection(10, 18     );
		graph.addConnection(10, 22     );
		graph.addConnection(10, 15     );
		graph.addConnection(10, 20     );
		graph.addConnection(10, 25     );
		graph.addConnection(10, 9      );
		graph.addConnection(10, 8      );
		graph.addConnection(10, 7      );
		graph.addConnection(10, 6      );
		graph.addConnection(10, 5      );
		graph.addConnection(10, 4      );
		graph.addConnection(11, 17     );
		graph.addConnection(11, 23     );
		graph.addConnection(11, 12     );
		graph.addConnection(11, 13     );
		graph.addConnection(11, 14     );
		graph.addConnection(11, 15     );
		graph.addConnection(11, 16     );
		graph.addConnection(11, 21     );
		graph.addConnection(11, 7      );
		graph.addConnection(11, 6      );
		graph.addConnection(11, 3      );
		graph.addConnection(11, 1      );
		graph.addConnection(12, 18     );
		graph.addConnection(12, 24     );
		graph.addConnection(12, 16     );
		graph.addConnection(12, 13     );
		graph.addConnection(12, 14     );
		graph.addConnection(12, 15     );
		graph.addConnection(12, 17     );
		graph.addConnection(12, 22     );
		graph.addConnection(12, 11     );
		graph.addConnection(12, 8      );
		graph.addConnection(12, 7      );
		graph.addConnection(12, 6      );
		graph.addConnection(12, 4      );
		graph.addConnection(12, 2      );
		graph.addConnection(13, 19     );
		graph.addConnection(13, 25     );
		graph.addConnection(13, 17     );
		graph.addConnection(13, 21     );
		graph.addConnection(13, 14     );
		graph.addConnection(13, 15     );
		graph.addConnection(13, 18     );
		graph.addConnection(13, 23     );
		graph.addConnection(13, 12     );
		graph.addConnection(13, 11     );
		graph.addConnection(13, 9      );
		graph.addConnection(13, 8      );
		graph.addConnection(13, 7      );
		graph.addConnection(13, 5      );
		graph.addConnection(13, 3      );
		graph.addConnection(13, 1      );
		graph.addConnection(14, 20     );
		graph.addConnection(14, 18     );
		graph.addConnection(14, 22     );
		graph.addConnection(14, 15     );
		graph.addConnection(14, 19     );
		graph.addConnection(14, 24     );
		graph.addConnection(14, 13     );
		graph.addConnection(14, 12     );
		graph.addConnection(14, 11     );
		graph.addConnection(14, 10     );
		graph.addConnection(14, 9      );
		graph.addConnection(14, 8      );
		graph.addConnection(14, 4      );
		graph.addConnection(14, 2      );
		graph.addConnection(15, 19     );
		graph.addConnection(15, 23     );
		graph.addConnection(15, 20     );
		graph.addConnection(15, 25     );
		graph.addConnection(15, 14     );
		graph.addConnection(15, 13     );
		graph.addConnection(15, 12     );
		graph.addConnection(15, 11     );
		graph.addConnection(15, 10     );
		graph.addConnection(15, 9      );
		graph.addConnection(15, 5      );
		graph.addConnection(15, 3      );
		graph.addConnection(16, 22     );
		graph.addConnection(16, 17     );
		graph.addConnection(16, 18     );
		graph.addConnection(16, 19     );
		graph.addConnection(16, 20     );
		graph.addConnection(16, 21     );
		graph.addConnection(16, 12     );
		graph.addConnection(16, 11     );
		graph.addConnection(16, 8      );
		graph.addConnection(16, 6      );
		graph.addConnection(16, 4      );
		graph.addConnection(16, 1      );
		graph.addConnection(17, 23     );
		graph.addConnection(17, 21     );
		graph.addConnection(17, 18     );
		graph.addConnection(17, 19     );
		graph.addConnection(17, 20     );
		graph.addConnection(17, 22     );
		graph.addConnection(17, 16     );
		graph.addConnection(17, 13     );
		graph.addConnection(17, 12     );
		graph.addConnection(17, 11     );
		graph.addConnection(17, 9      );
		graph.addConnection(17, 7      );
		graph.addConnection(17, 5      );
		graph.addConnection(17, 2      );
		graph.addConnection(18, 24     );
		graph.addConnection(18, 22     );
		graph.addConnection(18, 19     );
		graph.addConnection(18, 20     );
		graph.addConnection(18, 23     );
		graph.addConnection(18, 17     );
		graph.addConnection(18, 16     );
		graph.addConnection(18, 14     );
		graph.addConnection(18, 13     );
		graph.addConnection(18, 12     );
		graph.addConnection(18, 10     );
		graph.addConnection(18, 8      );
		graph.addConnection(18, 6      );
		graph.addConnection(18, 3      );
		graph.addConnection(19, 25     );
		graph.addConnection(19, 23     );
		graph.addConnection(19, 20     );
		graph.addConnection(19, 24     );
		graph.addConnection(19, 18     );
		graph.addConnection(19, 17     );
		graph.addConnection(19, 16     );
		graph.addConnection(19, 15     );
		graph.addConnection(19, 14     );
		graph.addConnection(19, 13     );
		graph.addConnection(19, 9      );
		graph.addConnection(19, 7      );
		graph.addConnection(19, 4      );
		graph.addConnection(19, 1      );
		graph.addConnection(20, 24     );
		graph.addConnection(20, 25     );
		graph.addConnection(20, 19     );
		graph.addConnection(20, 18     );
		graph.addConnection(20, 17     );
		graph.addConnection(20, 16     );
		graph.addConnection(20, 15     );
		graph.addConnection(20, 14     );
		graph.addConnection(20, 10     );
		graph.addConnection(20, 8      );
		graph.addConnection(20, 5      );
		graph.addConnection(20, 2      );
		graph.addConnection(21, 22     );
		graph.addConnection(21, 23     );
		graph.addConnection(21, 24     );
		graph.addConnection(21, 25     );
		graph.addConnection(21, 17     );
		graph.addConnection(21, 16     );
		graph.addConnection(21, 13     );
		graph.addConnection(21, 11     );
		graph.addConnection(21, 9      );
		graph.addConnection(21, 6      );
		graph.addConnection(21, 5      );
		graph.addConnection(21, 1      );
		graph.addConnection(22, 23     );
		graph.addConnection(22, 24     );
		graph.addConnection(22, 25     );
		graph.addConnection(22, 21     );
		graph.addConnection(22, 18     );
		graph.addConnection(22, 17     );
		graph.addConnection(22, 16     );
		graph.addConnection(22, 14     );
		graph.addConnection(22, 12     );
		graph.addConnection(22, 10     );
		graph.addConnection(22, 7      );
		graph.addConnection(22, 2      );
		graph.addConnection(23, 24     );
		graph.addConnection(23, 25     );
		graph.addConnection(23, 22     );
		graph.addConnection(23, 21     );
		graph.addConnection(23, 19     );
		graph.addConnection(23, 18     );
		graph.addConnection(23, 17     );
		graph.addConnection(23, 15     );
		graph.addConnection(23, 13     );
		graph.addConnection(23, 11     );
		graph.addConnection(23, 8      );
		graph.addConnection(23, 3      );
		graph.addConnection(24, 25     );
		graph.addConnection(24, 23     );
		graph.addConnection(24, 22     );
		graph.addConnection(24, 21     );
		graph.addConnection(24, 20     );
		graph.addConnection(24, 19     );
		graph.addConnection(24, 18     );
		graph.addConnection(24, 14     );
		graph.addConnection(24, 12     );
		graph.addConnection(24, 9      );
		graph.addConnection(24, 6      );
		graph.addConnection(24, 4      );
		graph.addConnection(25, 24     );
		graph.addConnection(25, 23     );
		graph.addConnection(25, 22     );
		graph.addConnection(25, 21     );
		graph.addConnection(25, 20     );
		graph.addConnection(25, 19     );
		graph.addConnection(25, 15     );
		graph.addConnection(25, 13     );
		graph.addConnection(25, 10     );
		graph.addConnection(25, 7      );
		graph.addConnection(25, 5      );
		graph.addConnection(25, 1      );
		
		for(Node n : graph.getNodes()){
			n.setColor((int)Random.uniform(0, 25));
		}
		
		System.out.println(Arrays.toString(graph.getColors()));
		
		repair(graph);
		
		System.out.println(Arrays.toString(graph.getColors()));
		
		int[] cols = graph.getColors();
		normalize(cols);
		
		System.out.println(Arrays.toString(cols));
		
		Set<Integer> colorsSet = new HashSet<>();
		int ratingModifier = 0;
		graph.setUpColors(cols);
		
		for(Node n : graph.getNodes()){
			colorsSet.add(n.getColor());
			for(Node connectedNode : n.getConnections()){
				if(n.getColor() == connectedNode.getColor()){
					ratingModifier = ratingModifier + AlgorithmSettings.EVALUATION_PUNISHMENT;
				}
			}
		}
		System.out.println("Colors: "+(colorsSet.size()+" ; Punishment: "+ratingModifier));
		
		
		System.out.println(5/2);
		System.out.println((double)5/2);
	}
	
	private static void repair(BaseGraph graph) {
		for(Node n : graph.getNodes()){
			while(!validateNode(n)){
				n.setColor(n.getColor()-1);
				if(n.getColor() < 0){
					n.setColor(graph.getSize()-1);
				}
			}
		}
	}
	
	private static boolean validateNode(Node n){
		for(Node connected : n.getConnections()){
			if(n.getColor() == connected.getColor())
				return false;
		}
		return true;
	}
	
	private static void normalize(int[] colors) {
		Map<Integer, Integer> colorMapper = new HashMap<Integer, Integer>();
		for (int i = 0; i < colors.length; i++) {
			if(!colorMapper.containsKey(colors[i])){
				colorMapper.put(colors[i], colorMapper.size());
			}
		}
		for (int i = 0; i < colors.length; i++) {
			colors[i] = colorMapper.get(colors[i]);
		}
	}
}
